package com.ssm.websocket.entrance;

import lombok.RequiredArgsConstructor;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.stereotype.Controller;

import java.security.Principal;

/**
 * https://www.cnblogs.com/ll409546297/p/10655392.html
 */
@Controller
@RequiredArgsConstructor
public class StompController {
    final SimpUserRegistry simpUserRegistry;
    final SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/broadcast")
    public Object broadcast(String message) { // 广播
        simpMessagingTemplate.convertAndSend("/queue/broadcast", message);
        return message; // 相当于 @SendTo("/topic/broadcast")
    }

    @SubscribeMapping("/subscribe/{id}")
    public Object subscribe(@DestinationVariable Long id, StompHeaderAccessor accessor) { // 只在订阅时触发
        return "@SubscribeMapping-" + id + "：" + accessor.getSessionId();
    }

    @MessageMapping("/user")
    @SendToUser("/queue/my")
    public Object user(String message, Principal principal, StompHeaderAccessor accessor) {
        // https://docs.spring.io/spring-framework/reference/web/websocket/stomp/user-destination.html
        simpMessagingTemplate.convertAndSendToUser(accessor.getSessionId(), "/queue/my", message, accessor.getMessageHeaders());
        simpMessagingTemplate.convertAndSend(simpMessagingTemplate.getUserDestinationPrefix() + accessor.getSessionId() + "/queue/my", message, accessor.getMessageHeaders());
        return message;
    }

    @MessageExceptionHandler
    public Throwable handleException(Throwable throwable) {
        return throwable;
    }
}